/*
 * write_location.c
 *
 *  Created on: 2012/09/04
 *      Author: shenming
 */

#include <stdio.h>
#include "sqlite3.h"
#include "db_def.h"
#include "core.h"
#include "core_internal.h"
#include "Id.h"
#include "../../CCore/table/table.h"
#include "../../CCore/table/core_table.h"

static CHAR pathBuf[OS_FULLPATH];

/*TBL_FILEINDEX*/
static INT insertFileIndex(sqlite3 *db) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stCoreFileIndexAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?,?,?);",
			TBL_FILEINDEX);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {
		sqlite3_bind_int(stmt, P_TABLE_INDEX, i);

		stCoreFileIndexAccess.getFile(i, pathBuf, OS_FULLPATH);
		sqlite3_bind_text(stmt, FILE_FILE_PATH, pathBuf, -1, SQLITE_STATIC );

		sqlite3_bind_int(stmt, FILE_MODIFY_TIME,
				stCoreFileIndexAccess.getModifyTime(i));

		sqlite3_bind_int64(stmt, FILE_FILE_SIZE,
				stCoreFileIndexAccess.getSize(i));

		sqlite3_bind_int(stmt, FILE_IS_FOLDER,
				stCoreFileIndexAccess.isFolder(i));

		sqlite3_bind_int(stmt, FILE_IS_EXISTED,
				stCoreFileIndexAccess.isExisted(i));

		sqlite3_bind_int(stmt, FILE_TRANSUNIT,
				stCoreFileIndexAccess.transUnit.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

/*TBL_CODESCOPE*/
static INT insertCodeScope(sqlite3 *db) {
	INT rc = 0;
	sqlite3_stmt * stmt;
	const char *zTail;
	PSZ sql_insert = NULL;
	BOOL bIsErr = FALSE;

	AST max = 0;
	AST i = 0;

	rc = sqlite3_exec(db, "begin;", 0, 0, 0);
	if (rc != SQLITE_OK) {
		return rc;
	}

	max = stCoreCodeScpAccess.getMax();

	sql_insert = sqlite3_mprintf("INSERT INTO %q VALUES(?,?,?,?,?,?);",
			TBL_CODESCOPE);
	rc = sqlite3_prepare(db, sql_insert, -1, &stmt, &zTail);
	if (rc != SQLITE_OK || stmt == NULL ) {
		if (sql_insert != NULL ) {
			sqlite3_free(sql_insert);
		}
		if (stmt != NULL ) {
			sqlite3_finalize(stmt);
		}
		return COEXIT_ERROR;
	}

	for (i = 1; i <= max; i++) {
		sqlite3_bind_int(stmt, P_TABLE_INDEX, i);

		sqlite3_bind_int(stmt, SCOPE_FILE_INDEX_INFO,
				stCoreCodeScpAccess.fileindex.get(i));

		sqlite3_bind_int(stmt, SCOPE_BEGIN_LINE,
				stCoreCodeScpAccess.startLine.get(i));

		sqlite3_bind_int(stmt, SCOPE_END_LINE,
				stCoreCodeScpAccess.endLine.get(i));

		sqlite3_bind_int(stmt, SCOPE_BEGIN_LINE_OFFSET,
				stCoreCodeScpAccess.startOffset.get(i));

		sqlite3_bind_int(stmt, SCOPE_END_LINE_OFFSET,
				stCoreCodeScpAccess.endOffset.get(i));

		rc = sqlite3_step(stmt);
		if (rc != SQLITE_DONE) {
			bIsErr = TRUE;
			printf("%s", sqlite3_errmsg(db));
			break;
		}
		sqlite3_reset(stmt);
	}

	if (bIsErr) {
		rc = sqlite3_exec(db, "rollback;", 0, 0, 0);
	} else {
		rc = sqlite3_exec(db, "commit;", 0, 0, 0);
	}

	if (sql_insert != NULL ) {
		sqlite3_free(sql_insert);
	}
	if (stmt != NULL ) {
		rc = sqlite3_finalize(stmt);
	}
	return rc;
}

INT DLL_EXPORT insertLocation(sqlite3 *db) {
	INT rc = 0;

	rc = insertFileIndex(db);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	rc = insertCodeScope(db);
	if (rc != COEXIT_SUCCESS) {
		return rc;
	}

	return COEXIT_SUCCESS;
}
